﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace PACKETPARSERMAX20.CORE
{
    public class Serializer
    {
        /// <summary>
        /// Returns the target namespace for the serializer.
        /// </summary>
        public static string TargetNamespace
        {
            get
            {
                return "http://www.w3.org/2001/XMLSchema";
            }
        }
        /// <summary>
        /// Returns the set of included namespaces for the serializer.
        /// </summary>
        /// <returns>
        /// The set of included namespaces for the serializer.
        /// </returns>
        public static XmlSerializerNamespaces GetNamespaces(bool pSuportNamespaces)
        {
            XmlSerializerNamespaces ns;
            ns = new XmlSerializerNamespaces();
            if (!pSuportNamespaces)
            {
                ns.Add("", "");
            }
            //ns.Add("", "");
            //ns.Add("xs", "http://www.w3.org/2001/XMLSchema");
            //ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            return ns;
        }


        private static bool DoesSuportNamespaces(System.Type pObjType)
        {
            System.Xml.Serialization.XmlTypeAttribute tAttr = (System.Xml.Serialization.XmlTypeAttribute)Attribute.GetCustomAttribute(pObjType, typeof(System.Xml.Serialization.XmlTypeAttribute));
            return tAttr != null;
        }

        private static bool mPrettyPrint = true;
        /// <summary>
        /// Get or sets the pretty print property.
        /// </summary>
        /// <remarks>
        /// If <b>true</b>, the XML output by the
        /// <see cref="ToXml" /> method is indented in
        /// a hierarchichal manner using one tab character
        /// per level, each level being on a new line. 
        /// If <b>false</b>, no indentation or newline
        /// characters are set in the output.
        /// </remarks>
        public static bool PrettyPrint
        {
            get
            {
                return Serializer.mPrettyPrint;
            }
            set
            {
                Serializer.mPrettyPrint = value;
            }
        }

        /// <summary>
        /// Serializes the <i>Obj</i> to an XML string.
        /// </summary>
        /// <param name="Obj">
        /// The object to serialize.</param>
        /// <param name="ObjType">The object type.</param>
        /// <returns>
        /// The serialized object XML string.
        /// </returns>
        /// <remarks>
        /// The <see cref="PrettyPrint" /> property provides
        /// an easy-to-read formatted XML string.
        /// </remarks>
        public static string ToXml(object Obj, System.Type ObjType)
        {
            bool tSupNamespases = DoesSuportNamespaces(ObjType);
            XmlSerializer ser;
            ser = new XmlSerializer(ObjType);//, Serializer.TargetNamespace
            MemoryStream memStream;
            //            ObjType.Attributes
            System.Reflection.MemberInfo tInfo = ObjType;
            memStream = new MemoryStream();
            XmlTextWriter xmlWriter;

            xmlWriter = new XmlTextWriter(memStream, Encoding.Unicode);


            if (Serializer.PrettyPrint)
            {
                xmlWriter.Formatting = Formatting.Indented;
                xmlWriter.Indentation = 1;
                xmlWriter.IndentChar = Convert.ToChar(9);
            }
            xmlWriter.Namespaces = true;
            ser.Serialize(xmlWriter, Obj, Serializer.GetNamespaces(tSupNamespases));
            xmlWriter.Close();
            memStream.Close();
            string xml;
            xml = Encoding.Unicode.GetString(memStream.GetBuffer());
            xml = xml.Substring(xml.IndexOf(Convert.ToChar(60)));
            xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1));
            return xml;
        }
        /// <summary>
        /// Creates an object from an XML string.
        /// </summary>
        /// <param name="Xml">
        /// XML string to serialize.</param>
        /// <param name="ObjType">The object type to create.</param>
        /// <returns>
        /// An object of type <i>ObjType</i>.
        /// </returns>
        public static object FromXml(string Xml, System.Type ObjType)
        {
            XmlSerializer ser;
            ser = new XmlSerializer(ObjType);
            StringReader stringReader;
            stringReader = new StringReader(Xml);
            XmlTextReader xmlReader;
            //xmlReader = new XmlTextReader2(stringReader, new StringReader(Xml));
            xmlReader = new XmlTextReader(stringReader);
            object obj;

            if (ser.CanDeserialize(xmlReader))
            {
                obj = ser.Deserialize(xmlReader);
                xmlReader.Close();
                stringReader.Close();
                return obj;
            }

            return null;
        }
    }
}
